package com.lanyou.esb.service;

import java.text.Collator;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import com.lanyou.cook.web.param.TreeNode;
import com.lanyou.esb.common.CommonUtils;

/**
 * HTTP树型结构服务
 * 
 * @author Davey.wu
 *
 */
@Service
public class TreeHttpService {

	@PersistenceContext
	private EntityManager entityManager;

	/**
	 * 构建HTTP树型结构
	 * 
	 * @param userId
	 *            ：用户标识
	 * @param auditStatus
	 *            ：审核状态
	 * @param operateType
	 *            ：操作类型
	 * @return
	 */
	public TreeSet<TreeNode> getLevel2Tree(String userId, String auditStatus,
			String operateType) {
		// 获取树型信息
		List<Object[]> objects = getLevel2Info(userId, auditStatus, operateType);
		// 无数据，返回空树
		if (objects == null || objects.isEmpty()) {
			return new TreeSet<>();
		}
		Collator chineseCmp = Collator.getInstance(java.util.Locale.CHINA);
		Comparator<TreeNode> comparator = Comparator.comparing(
				TreeNode::getText, chineseCmp);
		List<String> systemIds = new ArrayList<>();
		// 组建树形对象，利用TreeSet进行排序
		TreeSet<TreeNode> fieldNodes = new TreeSet<>(comparator);
		objects.forEach(object -> {
			String fieldId = (String) object[0];
			String fieldName = (String) object[1];
			String systemId = object[2] != null ? (String) object[2] : "";
			String systemName = object[3] != null ? (String) object[3] : "";
			String haveIf = object[4] != null ? (String) object[4] : "";
			// 保存系统标识
			systemIds.add(systemId);
			// 设置领域树节点
			TreeNode fieldNode = CollectionUtils.find(fieldNodes,
					n -> StringUtils.equals(fieldId, n.getId()));
			if (fieldNode == null) {
				fieldNode = new TreeNode();
				fieldNode.setNodeType(CommonUtils.TREE_NODE_TYPE_FIELD);
				fieldNode.setId(fieldId);
				fieldNode.setText(fieldName);
				fieldNode.setChildren(new TreeSet<>(comparator));
				fieldNodes.add(fieldNode);
			}

			if (systemId == null) {
				return;
			}
			// 设置系统树节点
			TreeNode systemNode = CollectionUtils.find(fieldNode.getChildren(),
					n -> StringUtils.equals(systemId, n.getId()));
			if (systemNode == null) {
				systemNode = new TreeNode();
				systemNode.setNodeType(CommonUtils.TREE_NODE_TYPE_FIELD_SYSTEM);
				systemNode.setId(systemId);
				systemNode.setText(systemName);
				systemNode.setChildren(new TreeSet<>(comparator));
				fieldNode.getChildren().add(systemNode);
				if (StringUtils.isNotBlank(haveIf) && "1".equals(haveIf)) {
					systemNode.setHasChildren(true);
				} else {
					systemNode.setHasChildren(false);
				}
			}
		});
		return fieldNodes;
	}

	/**
	 * 获取树信息：<br>
	 * 第一级节点：领域；第二级节点：系统
	 * 
	 * @param userId
	 *            ：用户标识
	 * @param auditStatus
	 *            ：审核状态
	 * @param operateType
	 *            ：操作类型
	 * @return
	 */
	public List<Object[]> getLevel2Info(String userId, String auditStatus,
			String operateType) {
		StringBuilder builder = new StringBuilder();
		builder.append("SELECT ");
		builder.append("f.field_id fieldId,");
		builder.append("f.field_name AS fieldName, ");
		builder.append("s.field_system_id AS systemId, ");
		builder.append("s.system_name AS systemName, ");
		// 判断对当前用户，该系统是否存在可见的接口，start===================
		builder.append("CASE ");
		builder.append("WHEN ");
		builder.append("	EXISTS( ");
		builder.append("		SELECT h.IF_HTTP_ID FROM t_esb_bu_if_http h ");
		builder.append("		WHERE h.FIELD_SYSTEM_ID=s.field_system_id ");
		builder.append("		AND h.IS_ENABLE='1' ");
		// 是否对审核状态进行判断
		if (StringUtils.isNotBlank(auditStatus)) {
			builder.append("		AND h.AUDIT_STATUS=:auditStatus ");
		}
		// 是否对操作类型进行判断
		if (StringUtils.isNotBlank(auditStatus)) {
			builder.append("		AND h.IF_OPERATE_TYPE=:operateType ");
		}
		builder.append("		AND( ");
		// #是公共接口，符合条件；
		builder.append("			h.IS_PUBLIC='1' ");
		// #是用户管理的系统，符合条件；
		builder.append("			OR EXISTS( ");
		builder.append("				SELECT us.field_system_id ");
		builder.append("				FROM t_cook_bu_user_system us ");
		builder.append("				INNER JOIN t_cook_db_user u ON us.user_id=u.user_id ");
		builder.append("				WHERE us.field_system_id=h.field_system_id AND u.user_id=:userId ");
		builder.append("			) ");
		// #是可用且已审核的接口，并且接口是公共的或者接口对当前用户所管理的系统可见，符合条件；
		builder.append("			OR( ");
		builder.append("				h.IS_ENABLE='1' ");
		builder.append("				AND h.audit_status='1' ");
		builder.append("				AND EXISTS( ");
		builder.append("					SELECT v.IF_ID ");
		builder.append("						FROM t_esb_bu_if_visiblity v ");
		builder.append("						INNER JOIN t_cook_bu_user_system us ON v.IF_VISIBLE_SYSTEM_ID=us.field_system_id ");
		builder.append("						INNER JOIN t_cook_db_user u ON us.user_id=u.user_id ");
		builder.append("						WHERE v.IF_ID=h.IF_HTTP_ID AND u.user_id=:userId ");
		builder.append("				) ");
		builder.append("			) ");
		builder.append("		)");
		builder.append("	) ");
		// 存在可见的接口，设置返回值为‘1’
		builder.append("THEN '1' ");
		// 不存在可见的接口，设置返回值为‘0’
		builder.append("ELSE '0' ");
		builder.append("END AS haveHttp ");
		// 判断对当前用户，该系统是否存在可见的接口，end===================
		builder.append("FROM t_cook_db_field f ");
		builder.append("LEFT OUTER JOIN t_cook_bu_field_system s ON f.field_id=s.field_id ");
		builder.append("	AND ( ");
		// #存在用户管理的系统
		builder.append("		EXISTS( ");
		builder.append("			SELECT us.field_system_id ");
		builder.append("			FROM t_cook_bu_user_system us ");
		builder.append("			INNER JOIN t_cook_db_user u ON us.user_id=u.user_id ");
		builder.append("			WHERE us.field_system_id=s.field_system_id AND u.user_id=:userId ");
		builder.append("		) ");
		// #存在可用且已审核的接口，并且接口是公共的或者接口对当前用户所管理的系统可见
		builder.append("		OR EXISTS( ");
		builder.append("			SELECT h.IF_HTTP_ID ");
		builder.append("			FROM t_esb_bu_if_http h ");
		builder.append("			WHERE h.field_system_id=s.field_system_id ");
		builder.append("			AND h.IS_ENABLE='1' ");
		builder.append("			AND h.audit_status='1' ");
		builder.append("			AND ( ");
		// #存在公共接口
		builder.append("				h.is_public='1' ");
		builder.append("");
		// #或者，接口对当前用户所管理的系统可见
		builder.append("				OR EXISTS( ");
		builder.append("					SELECT v.IF_ID ");
		builder.append("					FROM t_esb_bu_if_visiblity v ");
		builder.append("					INNER JOIN t_cook_bu_user_system us ON v.IF_VISIBLE_SYSTEM_ID=us.field_system_id ");
		builder.append("					INNER JOIN t_cook_db_user u ON us.user_id=u.user_id ");
		builder.append("					WHERE v.IF_ID=h.IF_HTTP_ID AND u.user_id=:userId ");
		builder.append("				) ");
		builder.append("			) ");
		builder.append("		) ");
		builder.append("	)");

		Query query = entityManager.createNativeQuery(builder.toString());
		query.setParameter("userId", userId);
		// 审核状态
		if (StringUtils.isNotBlank(auditStatus)) {
			query.setParameter("auditStatus", auditStatus);
		}
		// 操作类型
		if (StringUtils.isNotBlank(operateType)) {
			query.setParameter("operateType", operateType);
		}

		return query.getResultList();
	}

}
